package framework

import (
	"context"
	"encoding/json"
	"net/http"
	"sync"
	"time"
)

type ControllerHandler func(c *Context) error

type Context struct {
	request        *http.Request
	responseWriter http.ResponseWriter

	writerMutex *sync.Mutex
	hasTimeout  bool
}

func NewContext(r *http.Request, w http.ResponseWriter) *Context {
	ctx := &Context{}
	ctx.request = r
	ctx.responseWriter = w
	return ctx
}

// base
func (ctx *Context) WriterMux() *sync.Mutex {
	return ctx.writerMutex
}

func (ctx *Context) GetRequest() *http.Request {
	return ctx.request
}

func (ctx *Context) GetResponse() http.ResponseWriter {
	return ctx.responseWriter
}

func (ctx *Context) SetHasTimeout(hasTimeout bool) {
	ctx.hasTimeout = hasTimeout
}

func (ctx *Context) HasTimeout() bool {
	return ctx.hasTimeout
}

// context
func (ctx *Context) BaseContext() context.Context {
	return ctx.request.Context()
}

func (ctx *Context) Deadline() (deadline time.Time, ok bool) {
	return ctx.BaseContext().Deadline()
}

func (ctx *Context) Done() <-chan struct{} {
	return ctx.BaseContext().Done()
}

func (ctx *Context) Err() error {
	return ctx.BaseContext().Err()
}

func (ctx *Context) Value(key any) any {
	return ctx.BaseContext().Value(key)
}

// request
func (ctx *Context) QueryXXX() {

}

func (ctx *Context) FormXXX() {

}

func (ctx *Context) BindJson(obj any) {

}

// response
func (ctx *Context) Json(status int, obj any) error {
	if ctx.hasTimeout {
		return nil
	}
	ctx.responseWriter.WriteHeader(status)
	bytes, err := json.Marshal(obj)
	if err != nil {
		ctx.responseWriter.WriteHeader(500)
		return err
	}
	ctx.responseWriter.Write(bytes)
	return nil
}

func (ctx *Context) HTML(status int, obj any) {

}

func (ctx *Context) Text(status int, obj any) {

}
